package regionsrvlogic

import (
	"context"
	"math"
	"strconv"
	"strings"

	"gozero-microservices/common-service/rpc/internal/model"
	"gozero-microservices/common-service/rpc/internal/svc"
	"gozero-microservices/common-service/rpc/types/common"
	"gozero-microservices/gateway-api/utils"

	"github.com/zeromicro/go-zero/core/logx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type RegionLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewRegionLogicInstance(ctx context.Context, svcCtx *svc.ServiceContext) *RegionLogic {
	return &RegionLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *RegionLogic) AddRegion(in *common.AddRegionRequest) (*common.Result, error) {
	// todo: add your logic here and delete this line

	return &common.Result{}, nil
}

/**
 * 详情
 *
 * @param uint64 Id ---------------------------必传,Id
 * @return *common.Region, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *RegionLogic) RegionDetail(in *common.DetailRequest) (*common.Region, error) {
	if in.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	// 操作数据库
	regionRes, err := l.svcCtx.RegionModel.FindOne(l.ctx, int64(in.Id))
	if err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return nil, status.Errorf(codes.Aborted, "区域信息错误")
		}

		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Region{
		Id:    uint32(regionRes.Id),
		Pid:   uint32(regionRes.Pid),
		Name:  regionRes.Name,
		Level: uint32(regionRes.Level),
		Sort:  uint32(regionRes.Sort),
		IsHot: uint32(regionRes.IsHot),
	}, nil
}

/**
 * 列表
 *
 * @param uint32 Id ---------------------------非必传,Id
 * @param string Ids --------------------------非必传,Id支持多个
 * @param string Pid --------------------------非必传,父级Id
 * @param string Pids -------------------------非必传,父级Id支持多个
 * @param string Name -------------------------非必传,名称
 * @param uint32 Level ------------------------非必传,级别
 * @param string IsHot ------------------------非必传,是否热门
 * @param string SortField --------------------非必传,排序字段
 * @param string SortType ---------------------非必传,排序方式
 * @param int32 PageSize ----------------------非必传,条数
 * @param uint32 Page -------------------------非必传,页码
 * @return *common.RegionListResponse, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *RegionLogic) RegionList(in *common.QueryRegionRequest) (*common.RegionListResponse, error) {
	params := map[string]interface{}{}

	page := in.Page
	pageSize := in.PageSize
	sortType := in.SortType
	sortField := in.SortField
	if in.Id > 0 {
		params["id"] = in.Id
	}
	if in.Ids != "" {
		params["id IN (?)"] = utils.IntSplit(strings.TrimRight(in.Ids, ","), ",")
	}
	if in.Pid != "all" {
		pid, _ := strconv.Atoi(in.Pid)
		params["pid"] = pid
	}
	if in.Ids != "" {
		params["id IN (?)"] = utils.IntSplit(strings.TrimRight(in.Ids, ","), ",")
	}
	if in.Name != "" {
		params["name"] = in.Name
	}
	if in.Level > 0 {
		params["level"] = in.Level
	}
	if in.IsHot != "all" {
		params["is_hot"] = in.IsHot
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "id"
	}
	if sortType == "" {
		sortType = "desc"
	}

	// 查询数量
	total, err := l.svcCtx.RegionModel.GetResultsByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	var regions []*model.MallRegion
	if total > 0 {
		err = l.svcCtx.RegionModel.GetResultsByParams(l.ctx, &regions, params, page, int8(pageSize), sortField+" "+sortType)
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
	}

	// 组装数据
	regionItems := []*common.Region{}
	for _, region := range regions {
		regionItems = append(regionItems, &common.Region{
			Id:    uint32(region.Id),
			Pid:   uint32(region.Pid),
			Name:  region.Name,
			Level: uint32(region.Level),
			Sort:  uint32(region.Sort),
			IsHot: uint32(region.IsHot),
		})
	}

	// 计算总页数
	pageTotal := math.Ceil(float64(total) / float64(pageSize))

	return &common.RegionListResponse{
		Page:      page,
		PageSize:  pageSize,
		Total:     int32(total),
		PageTotal: int32(pageTotal),
		Regions:   regionItems,
	}, nil
}
